<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>EPUB</title>
  <!-- <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script> -->
  <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/detect_swipe/2.1.1/jquery.detect_swipe.min.js"></script> -->
	<script src="../dist/jszip.min.js"></script>
  <script src="../dist/epub.js"></script>


  <link rel="stylesheet" type="text/css" href="examples.css">

  <style type="text/css">
    body {
      display: flex;
      -webkit-align-items: center;
      -webkit-justify-content: center;
    }

    #viewer {
      width: 100%;
      height: 100%;
      /* width: 400px;
      height: 580px; */
      /* box-shadow: 0 0 4px #ccc; */
      /* padding: 10px 10px 0px 10px; */
      margin: 5px auto;
      background: white;
    }


    @media only screen
      and (min-device-width : 320px)
      and (max-device-width : 667px) {
        #viewer {
          /* height: 100vh; */
        }
        #viewer iframe {
          /* pointer-events: none; */
        }
        .arrow {
          position: inherit;
          display: none;
        }
    }

  </style>
</head>
<body>
  <div id="viewer"></div>
  <script>
    
    var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
    // var epubUrl = params && params.get("epubUrl") && decodeURIComponent(params.get("epubUrl"));
    var accessToken = (params && params.get("accessToken")) ? params.get("accessToken") : undefined;
    // var cfi = (params && params.get("cfi")) ? params.get("cfi") : undefined;
    // var displaySettings= (params && params.get("displaySettings")) ? params.get("displaySettings") : undefined;
    
   

    //loading epub
    var book = ePub();
    var rendition;
    var displayed;
    var chapters = []

    

    function loadBook(data, cfi, manager, flow, spread, snap,allowScriptedContent){
      var viewportHeight = window.innerHeight;
      document.getElementById('viewer').style.height = viewportHeight;
      var uint8Array = new Uint8Array(data)
      book.open(uint8Array,)
      rendition = book.renderTo("viewer", {
        manager: manager,
        flow: flow,
        // method: "continuous",
        spread:spread,
        width: "100vw",
        height: "100vh",
        snap: snap,
        allowScriptedContent: allowScriptedContent,
      });

      if(cfi){
        displayed = rendition.display(cfi)
      }else{
        displayed = rendition.display(1)
      }

      displayed.then(function(renderer){
        console.log("displayed")
        window.flutter_inappwebview.callHandler('displayed');
      });

      book.loaded.navigation.then(function(toc){
       chapters = parseChapters(toc)
       window.flutter_inappwebview.callHandler('chapters');
     })

      rendition.on("rendered" , function(){
        window.flutter_inappwebview.callHandler('rendered');
      })

     ///text selection callback
      rendition.on("selected", function(cfiRange,contents){
        book.getRange(cfiRange).then(function (range) {
          var selectedText = range.toString();
          var args = [cfiRange.toString(),selectedText]
          window.flutter_inappwebview.callHandler('selection', ...args);
        })
      });

      //book location changes callback
      rendition.on("relocated", function(location) {
        var percent = location.start.percentage;
        // var percentage = Math.floor(percent * 100);
        var location  = {
          startCfi: location.start.cfi,
          endCfi:location.end.cfi,
          progress: percent
        }
        var args = [location]
        window.flutter_inappwebview.callHandler('relocated', ...args);
      });

      rendition.on('displayError', function(e){
        console.log("displayError")
        window.flutter_inappwebview.callHandler('displayError');
      })

      rendition.on('markClicked', function(cfiRange){
        console.log("markClicked")
        var args = [cfiRange.toString()]
        window.flutter_inappwebview.callHandler('markClicked',...args);
      })

      book.ready.then(function(){
        book.locations.generate(1600)
      })

    }

    window.flutter_inappwebview.callHandler('readyToLoad');

    
    //move to next page
    function next(){
      rendition.next()
    }

    //move to previous page
    function previous(){
      rendition.prev()
    }

    //move to given cfi location
    function toCfi(cfi){
      rendition.display(cfi)
    }
    
    //get all chapters
    function getChapters(){
      return chapters;
    }


    function getCurrentLocation(){
      var percent = rendition.location.start.percentage;
      // var percentage = Math.floor(percent * 100);
      var location  = {
        startCfi: rendition.location.start.cfi,
        endCfi: rendition.location.end.cfi,
        progress: percent
      }
      return location; 
    }

    ///parsing chapters and subitems recursively
    var parseChapters = function(toc){
      var chapters = []
      toc.forEach(function(chapter){
          chapters.push({
            title: chapter.label,
            href: chapter.href,
            id:chapter.id,
            subitems: getChapters(chapter.subitems)
          })
        })
       return chapters; 
    }

    function searchInBook(query){
      search(query).then(function (data){
        var args = [data]
        window.flutter_inappwebview.callHandler('search', ...args);
      })
    }

    
    // adds highlight with given color
    function addHighlight(cfiRange, color, opacity){
      this.rendition.themes.default({
      // '::selection': {
      //   'background': 'rgba(255,255,0, 0.3)'
      // },
      // '.epubjs-hl' : {
      //   'fill': color, 'fill-opacity': '0.3', 'mix-blend-mode': 'multiply',
      //   // 'background': 'rgba(255,0,0, 0.3)'
      // }
      });
      rendition.annotations.highlight(cfiRange, {}, (e) => {
          // console.log("highlight clicked", e.target);
        },"hl", {"fill": color, "fill-opacity": '0.3', "mix-blend-mode": "multiply"});
    }

    function addUnderLine(cfiString){
      rendition.annotations.underline(cfiString)
    }

    function  addMark(cfiString){
      rendition.annotations.mark(cfiString)
    }

    function removeHighLight(cfiString){
         rendition.annotations.remove(cfiString, "highlight");
    }

    function removeUnderLine(cfiString){
         rendition.annotations.remove(cfiString, "underline");
    }

    function removeMark(cfiString){
         rendition.annotations.remove(cfiString, "mark");
    }

    function toProgress(progress){
      var cfi = book.locations.cfiFromPercentage(progress);
      rendition.display(cfi);
    }

    
    function search(q) {
      return Promise.all(
          book.spine.spineItems.map(item => item.load(book.load.bind(book)).then(item.find.bind(item, q)).finally(item.unload.bind(item)))
      ).then(results => Promise.resolve([].concat.apply([], results)));
    };

    function setFontSize(fontSize){
      rendition.themes.default({
        p: {
        // "margin": '10px',
        "font-size":`${fontSize}px`
      }
      });
    }

    function setSpread(spread){
      rendition.spread(spread);
    }

    function setFlow(flow){
      rendition.flow(flow);
    }

    function setManager(manager){
      rendition.manager(manager);
    }

    function setFontSize(fontSize){
      rendition.themes.default({
        p: {
        // "margin": '10px',
        "font-size":`${fontSize}px`
        }
      });
    }

    //get current page text
    function getCurrentPageText(){
      var startCfi = rendition.location.start.cfi
      var endCfi = rendition.location.end.cfi
      var cfiRange = makeRangeCfi(startCfi, endCfi)
      book.getRange(cfiRange).then(function (range){
        var text = range.toString();
        var args = [text, cfiRange]
        window.flutter_inappwebview.callHandler('epubText', ...args);
      })
    }

    //get text from a range
    function getTextFromCfi(startCfi, endCfi){
      var cfiRange = makeRangeCfi(startCfi, endCfi)
      book.getRange(cfiRange).then(function (range){
        var text = range.toString();
        var args = [text,cfiRange]
        window.flutter_inappwebview.callHandler('epubText', ...args);
      })
    }

    const makeRangeCfi = (a, b) => {
      const CFI = new ePub.CFI()
      const start = CFI.parse(a), end = CFI.parse(b)
      const cfi = {
          range: true,
          base: start.base,
          path: {
              steps: [],
              terminal: null
          },
          start: start.path,
          end: end.path
      }
      const len = cfi.start.steps.length
      for (let i = 0; i < len; i++) {
          if (CFI.equalStep(cfi.start.steps[i], cfi.end.steps[i])) {
              if (i == len - 1) {
                  // Last step is equal, check terminals
                  if (cfi.start.terminal === cfi.end.terminal) {
                      // CFI's are equal
                      cfi.path.steps.push(cfi.start.steps[i])
                      // Not a range
                      cfi.range = false
                  }
              } else cfi.path.steps.push(cfi.start.steps[i])
          } else break
      }
      cfi.start.steps = cfi.start.steps.slice(cfi.path.steps.length)
      cfi.end.steps = cfi.end.steps.slice(cfi.path.steps.length)

      return 'epubcfi(' + CFI.segmentString(cfi.base)
          + '!' + CFI.segmentString(cfi.path)
          + ',' + CFI.segmentString(cfi.start)
          + ',' + CFI.segmentString(cfi.end)
          + ')'
    }

    
  </script>

</body>
</html>
